﻿using System.Diagnostics.CodeAnalysis;
using System.Linq.Expressions;
using ZeroSum.Domain.Entities;

namespace ZeroSum.Domain.Repositories;

/// <summary>
///     非泛型仓库
/// </summary>
public interface IRepository
{
    #region 添加

    /// <summary>
    ///     新增实体
    /// </summary>
    /// <param name="entity"></param>
    /// <typeparam name="TEntity"></typeparam>
    /// <returns></returns>
    TEntity Add<TEntity>([NotNull] TEntity entity) where TEntity : class, IEntity;

    /// <summary>
    ///     异步新增实体
    /// </summary>
    /// <param name="entity"></param>
    /// <typeparam name="TEntity"></typeparam>
    /// <returns></returns>
    Task<TEntity> AddAsync<TEntity>([NotNull] TEntity entity) where TEntity : class, IEntity;

    /// <summary>
    ///     批量新增实体
    /// </summary>
    /// <param name="entities"></param>
    /// <typeparam name="TEntity"></typeparam>
    void AddRange<TEntity>(IEnumerable<TEntity> entities) where TEntity : class, IEntity;

    /// <summary>
    ///     异步批量新增实体
    /// </summary>
    /// <param name="entities"></param>
    /// <typeparam name="TEntity"></typeparam>
    /// <returns></returns>
    Task AddRangeAsync<TEntity>(IEnumerable<TEntity> entities) where TEntity : class, IEntity;

    #endregion

    #region 更新

    /// <summary>
    ///     更新实体
    /// </summary>
    /// <param name="entity"></param>
    /// <typeparam name="TEntity"></typeparam>
    /// <returns></returns>
    TEntity Update<TEntity>([NotNull] TEntity entity) where TEntity : class, IEntity;

    /// <summary>
    ///     异步更新实体
    /// </summary>
    /// <param name="entity"></param>
    /// <typeparam name="TEntity"></typeparam>
    /// <returns></returns>
    Task<TEntity> UpdateAsync<TEntity>([NotNull] TEntity entity) where TEntity : class, IEntity;

    /// <summary>
    ///     批量更新实体
    /// </summary>
    /// <param name="entities"></param>
    /// <typeparam name="TEntity"></typeparam>
    void UpdateRange<TEntity>(IEnumerable<TEntity> entities) where TEntity : class, IEntity;

    /// <summary>
    ///     异步批量更新实体
    /// </summary>
    /// <param name="entities"></param>
    /// <typeparam name="TEntity"></typeparam>
    /// <returns></returns>
    Task UpdateRangeAsync<TEntity>(IEnumerable<TEntity> entities) where TEntity : class, IEntity;

    #endregion

    #region 查询

    /// <summary>
    ///     查询单条数据
    /// </summary>
    /// <param name="query"></param>
    /// <typeparam name="TEntity"></typeparam>
    /// <returns></returns>
    TEntity Get<TEntity>(IQuery<TEntity> query) where TEntity : class, IEntity;

    /// <summary>
    ///     异步查询单条数据
    /// </summary>
    /// <param name="query"></param>
    /// <returns></returns>
    Task<TEntity> GetAsync<TEntity>(IQuery<TEntity> query) where TEntity : class, IEntity;

    /// <summary>
    ///     查询多条数据
    /// </summary>
    /// <param name="query"></param>
    /// <typeparam name="TEntity"></typeparam>
    /// <returns></returns>
    IList<TEntity> GetList<TEntity>(IQuery<TEntity> query) where TEntity : class, IEntity;

    /// <summary>
    ///     异步查询多条数据
    /// </summary>
    /// <param name="query"></param>
    /// <returns></returns>
    Task<IList<TEntity>> GetListAsync<TEntity>(IQuery<TEntity> query) where TEntity : class, IEntity;

    /// <summary>
    ///     查询单个实体
    /// </summary>
    /// <param name="predicate">查询表达式</param>
    /// <typeparam name="TEntity"></typeparam>
    /// <returns></returns>
    TEntity Get<TEntity>([NotNull] Expression<Func<TEntity, bool>> predicate) where TEntity : class, IEntity;

    /// <summary>
    ///     异步查询单个实体
    /// </summary>
    /// <param name="predicate">查询表达式</param>
    /// <typeparam name="TEntity"></typeparam>
    /// <returns></returns>
    Task<TEntity> GetAsync<TEntity>([NotNull] Expression<Func<TEntity, bool>> predicate) where TEntity : class, IEntity;

    /// <summary>
    ///     条件查询
    /// </summary>
    /// <param name="predicate">查询表达式</param>
    /// <typeparam name="TEntity"></typeparam>
    /// <returns></returns>
    IList<TEntity> GetList<TEntity>([NotNull] Expression<Func<TEntity, bool>> predicate) where TEntity : class, IEntity;

    /// <summary>
    ///     异步条件查询
    /// </summary>
    /// <param name="predicate">查询表达式</param>
    /// <typeparam name="TEntity"></typeparam>
    /// <returns></returns>
    Task<IList<TEntity>> GetListAsync<TEntity>([NotNull] Expression<Func<TEntity, bool>> predicate)
        where TEntity : class, IEntity;

    /// <summary>
    ///     分页查询
    /// </summary>
    /// <param name="pageNumber">要查询的第几页</param>
    /// <param name="pageSize">每页数量</param>
    /// <param name="sorting">排序</param>
    /// <typeparam name="TEntity"></typeparam>
    /// <returns></returns>
    IList<TEntity> GetPage<TEntity>(int pageNumber, int pageSize, Expression<Func<TEntity, object>> sorting)
        where TEntity : class, IEntity;

    /// <summary>
    ///     异步分页查询
    /// </summary>
    /// <param name="pageNumber">要查询的第几页</param>
    /// <param name="pageSize">每页数量</param>
    /// <param name="sorting">排序</param>
    /// <typeparam name="TEntity"></typeparam>
    /// <returns></returns>
    Task<IList<TEntity>> GetPageAsync<TEntity>(int pageNumber, int pageSize, Expression<Func<TEntity, object>> sorting)
        where TEntity : class, IEntity;

    #endregion

    #region 删除

    /// <summary>
    ///     删除实体
    /// </summary>
    /// <param name="entity"></param>
    /// <typeparam name="TEntity"></typeparam>
    void Remove<TEntity>([NotNull] TEntity entity) where TEntity : class, IEntity;

    /// <summary>
    ///     异步删除实体
    /// </summary>
    /// <param name="entity"></param>
    /// <typeparam name="TEntity"></typeparam>
    /// <returns></returns>
    Task RemoveAsync<TEntity>([NotNull] TEntity entity) where TEntity : class, IEntity;

    /// <summary>
    ///     条件删除实体
    /// </summary>
    /// <param name="predicate">条件表达式</param>
    /// <typeparam name="TEntity"></typeparam>
    void Remove<TEntity>([NotNull] Expression<Func<TEntity, bool>> predicate) where TEntity : class, IEntity;

    /// <summary>
    ///     异步条件删除实体
    /// </summary>
    /// <param name="predicate">条件表达式</param>
    /// <typeparam name="TEntity"></typeparam>
    /// <returns></returns>
    Task RemoveAsync<TEntity>([NotNull] Expression<Func<TEntity, bool>> predicate) where TEntity : class, IEntity;


    /// <summary>
    ///     批量删除
    /// </summary>
    /// <param name="entities"></param>
    /// <typeparam name="TEntity"></typeparam>
    void RemoveRange<TEntity>(IEnumerable<TEntity> entities) where TEntity : class, IEntity;

    /// <summary>
    ///     批量删除
    /// </summary
    /// <typeparam name="TEntity"></typeparam>
    void RemoveRange<TEntity>() where TEntity : class, IEntity;

    /// <summary>
    ///     异步批量删除
    /// </summary>
    /// <param name="entities"></param>
    /// <typeparam name="TEntity"></typeparam>
    /// <returns></returns>
    Task RemoveRangeAsync<TEntity>(IEnumerable<TEntity> entities) where TEntity : class, IEntity;

    /// <summary>
    ///     批量条件删除
    /// </summary>
    /// <param name="predicate">条件表达式</param>
    /// <typeparam name="TEntity"></typeparam>
    void RemoveRange<TEntity>(Expression<Func<TEntity, bool>> predicate) where TEntity : class, IEntity;

    /// <summary>
    ///     异步批量条件删除
    /// </summary>
    /// <param name="predicate">条件表达式</param>
    /// <typeparam name="TEntity"></typeparam>
    /// <returns></returns>
    Task RemoveRangeAsync<TEntity>(Expression<Func<TEntity, bool>> predicate) where TEntity : class, IEntity;


    /// <summary>
    ///     通过Query匹配删除单条记录
    /// </summary>
    /// <param name="query"></param>
    /// <typeparam name="TEntity"></typeparam>
    void Remove<TEntity>(IQuery<TEntity> query) where TEntity : class, IEntity;


    /// <summary>
    ///     异步通过Query匹配删除单条记录
    /// </summary>
    /// <param name="query"></param>
    /// <typeparam name="TEntity"></typeparam>
    /// <returns></returns>
    Task RemoveAsync<TEntity>(IQuery<TEntity> query) where TEntity : class, IEntity;

    /// <summary>
    ///     通过Query匹配删除多条记录
    /// </summary>
    /// <param name="query"></param>
    /// <typeparam name="TEntity"></typeparam>
    void RemoveRange<TEntity>(IQuery<TEntity> query) where TEntity : class, IEntity;

    /// <summary>
    ///     异步通过Query匹配删除多条记录
    /// </summary>
    /// <param name="query"></param>
    /// <typeparam name="TEntity"></typeparam>
    /// <returns></returns>
    Task RemoveRangeAsync<TEntity>(IQuery<TEntity> query) where TEntity : class, IEntity;

    #endregion

    #region 辅助方法

    /// <summary>
    ///     统计总数
    /// </summary>
    /// <typeparam name="TEntity"></typeparam>
    /// <returns></returns>
    int Count<TEntity>() where TEntity : class, IEntity;

    /// <summary>
    ///     异步统计总数
    /// </summary>
    /// <returns></returns>
    Task<int> CountAsync<TEntity>() where TEntity : class, IEntity;

    /// <summary>
    ///     查询是否存在符合条件的实体
    /// </summary>
    /// <param name="predicate">查询表达式</param>
    /// <typeparam name="TEntity"></typeparam>
    /// <returns></returns>
    bool Any<TEntity>(Expression<Func<TEntity, bool>> predicate) where TEntity : class, IEntity;

    /// <summary>
    ///     异步查询是否存在符合条件的实体
    /// </summary>
    /// <param name="predicate">查询表达式</param>
    /// <typeparam name="TEntity"></typeparam>
    /// <returns></returns>
    Task<bool> AnyAsync<TEntity>(Expression<Func<TEntity, bool>> predicate) where TEntity : class, IEntity;

    /// <summary>
    ///     查询是否实体是否存在
    /// </summary>
    /// <param name="query"></param>
    /// <typeparam name="TEntity"></typeparam>
    /// <returns></returns>
    bool Existed<TEntity>(IQuery<TEntity> query) where TEntity : class, IEntity;

    /// <summary>
    ///     异步查询实体是否存在
    /// </summary>
    /// <param name="query"></param>
    /// <returns></returns>
    Task<bool> ExistedAsync<TEntity>(IQuery<TEntity> query) where TEntity : class, IEntity;

    /// <summary>
    ///     统计总数
    /// </summary>
    /// <param name="query"></param>
    /// <typeparam name="TEntity"></typeparam>
    /// <returns></returns>
    int Count<TEntity>(IQuery<TEntity> query) where TEntity : class, IEntity;

    /// <summary>
    ///     异步统计总数
    /// </summary>
    /// <param name="query"></param>
    /// <returns></returns>
    Task<int> CountAsync<TEntity>(IQuery<TEntity> query) where TEntity : class, IEntity;

    #endregion

    #region 工作单元操作

    /// <summary>
    ///     保存修改
    /// </summary>
    void SaveChanges();

    /// <summary>
    ///     异步保存修改
    /// </summary>
    /// <returns></returns>
    Task SaveChangesAsync();

    #endregion
}